from dataclasses import dataclass, field
import json
from typing import List, Literal, Optional, TypedDict
from dataclasses_json import DataClassJsonMixin
from shared_types import DeviceFunctionalConfig, WifiConfig, ROLES, ConnectedMsg, ControlMsg, AudioControl, AUDIO_ACTIONS, BIDIR_SLFHLD_EM_STATES
from .messages import TractionModes
from .hardware import Turnout
from esp_toytrain_client import ESPObject

from ..communication.udp_sender import UDPSender


@dataclass
class WifiDevice(DataClassJsonMixin):
    name: str
    ip: str
    role: ROLES

    @classmethod
    def from_connected_msg(cls, msg: ConnectedMsg):
        return cls(name=msg["name"], ip=msg["ip"], role=msg["role"])

    def _send_control_msg(self, sender: UDPSender, msg: ControlMsg):
        sender.send(self.ip, json.dumps(msg).encode("ascii"))

    def send_audio_control_msg(self, sender: UDPSender, action: AUDIO_ACTIONS):
        ctrl_msg: ControlMsg = {
            "type": "ETT_DEVICE_CONTROL",
            "payload": AudioControl(kind="audio", cmd=action),
        }
        self._send_control_msg(sender, ctrl_msg)

    def set_speed(self, speed: int, direction: TractionModes):
        symbol = 1 if direction == 'forward' else (
            -1 if direction == 'reverse' else 0)
        ESPObject(self.ip, 80).set_speed((1024/100.0)*speed*symbol)

    def set_switch(self, switch_index: int, state: BIDIR_SLFHLD_EM_STATES):
        ESPObject(self.ip, 80).set_magnet(switch_index, state)


# WifiDevice的包装，用来保存相关的设置
# 可以同步到其他的WifiDevice中。


def new_device_config(uuid: str, device_name: str, role: ROLES, activated=True) -> DeviceFunctionalConfig:
    return {
        "uuid": uuid,
        "role": role,
        "activated": activated,
        "device_name": device_name,
        "motor_reversed": False,
        "alias": "",
        "drive_curve":   [
            i for i in range(128)],
        "electromagnet_595_chips": 1,
        "led_595_chips": 1,
    }
